package Console;

import Service.*;
import Service.impl.*;
import Domin.Employee;
import Domin.Attendance;
import Domin.Salary;
import Domin.Role;

import java.time.LocalDate;
import java.util.List;
import java.util.Scanner;
import java.util.Optional;

public class HRConsole {
    private final Scanner input = new Scanner(System.in);
    private final EmployeeService empService = new EmployeeServiceImpl();
    private final AttendanceService attService = new AttendanceServiceImpl();
    private final SalaryService salService = new SalaryServiceImpl();
    private final RoleService roleService = new RoleServiceImpl();

    private String currentUserName = null;
    private String currentUserRole = null;
    private static final int MAX_LOGIN_ATTEMPTS = 5;

    public void showLoginMenu() {
        int attempts = 0;
        while (currentUserName == null) {
            System.out.println("\n=== 人力资源管理系统 ===");
            System.out.println("1. 登录");
            System.out.println("2. 注册（仅员工）");
            System.out.println("0. 退出");
            String choice = input.nextLine().trim();
            switch (choice) {
                case "1":
                    if (!login()) {
                        attempts++;
                        if (attempts >= MAX_LOGIN_ATTEMPTS) {
                            System.out.println("登录尝试次数过多，程序退出。");
                            return;
                        }
                        System.out.println("登录失败，剩余尝试次数: " + (MAX_LOGIN_ATTEMPTS - attempts));
                    }
                    break;
                case "2":
                    register();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效输入。");
            }
        }
        showMainMenu();
    }

    private boolean login() {
        System.out.print("用户名: ");
        String u = input.nextLine().trim();
        System.out.print("密码: ");
        String p = input.nextLine().trim();
        if (u.isEmpty() || p.isEmpty()) {
            System.out.println("用户名或密码不能为空。");
            return false;
        }
        if (empService.login(u, p)) {
            currentUserName = u;
            currentUserRole = empService.getUserRole(u);
            System.out.println("登录成功！欢迎 " + u + " (" + currentUserRole + ")");
            return true;
        } else {
            System.out.println("用户名或密码错误。");
            return false;
        }
    }

    private void register() {
        System.out.print("设置用户名: ");
        String u = input.nextLine().trim();
        System.out.print("设置密码: ");
        String p = input.nextLine().trim();
        if (u.isEmpty() || p.isEmpty() || p.length() < 3) {
            System.out.println("用户名或密码无效（密码至少3位）。");
            return;
        }
        if (empService.addEmployee(u, "待分配", "待分配", "employee", p)) {
            System.out.println("注册成功，请登录。");
        } else {
            System.out.println("用户名已存在。");
        }
    }

    private void showMainMenu() {
        while (currentUserName != null) {
            System.out.println("\n=== 主菜单 ===");
            System.out.println("1. 员工管理");
            System.out.println("2. 考勤管理");
            System.out.println("3. 薪资管理");
            System.out.println("0. 退出");

            String choice = input.nextLine().trim();
            switch (choice) {
                case "1":
                    handleEmployeeMenu();
                    break;
                case "2":
                    handleAttendanceMenu();
                    break;
                case "3":
                    handleSalaryMenu();
                    break;
                case "0":
                    logout();
                    return;
                default:
                    System.out.println("无效输入。");
            }
        }
    }

    private void handleEmployeeMenu() {
        if (!hasPermission("employee")) return;
        while (true) {
            System.out.println("\n--- 员工管理 ---");
            System.out.println("1. 查看所有员工");
            if ("admin".equals(currentUserRole) || "hr".equals(currentUserRole)) {
                System.out.println("2. 添加员工");
                System.out.println("3. 修改员工");
                System.out.println("4. 删除员工");
            }
            System.out.println("0. 返回");
            String c = input.nextLine().trim();
            switch (c) {
                case "1":
                    viewAllEmployees();
                    break;
                case "2":
                    if (hasPermission("employee")) addEmployee();
                    break;
                case "3":
                    if (hasPermission("employee")) updateEmployee();
                    break;
                case "4":
                    if (hasPermission("employee")) deleteEmployee();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效输入。");
            }
        }
    }

    private void handleAttendanceMenu() {
        if (!hasPermission("attendance")) return;
        while (true) {
            System.out.println("\n--- 考勤管理 ---");
            System.out.println("1. 查看我的考勤");
            if ("admin".equals(currentUserRole) || "hr".equals(currentUserRole)) {
                System.out.println("2. 录入考勤");
                System.out.println("3. 查看所有考勤");
                System.out.println("4. 按日期查询考勤");
            }
            System.out.println("0. 返回");
            String c = input.nextLine().trim();
            switch (c) {
                case "1":
                    viewMyAttendance();
                    break;
                case "2":
                    if (hasPermission("attendance")) recordAttendance();
                    break;
                case "3":
                    if (hasPermission("attendance")) viewAllAttendance();
                    break;
                case "4":
                    if (hasPermission("attendance")) viewAttendanceByDate();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效输入。");
            }
        }
    }

    private void handleSalaryMenu() {
        if (!hasPermission("salary")) return;
        while (true) {
            System.out.println("\n--- 薪资管理 ---");
            System.out.println("1. 查看我的薪资");
            if ("admin".equals(currentUserRole) || "hr".equals(currentUserRole)) {
                System.out.println("2. 发放薪资");
                System.out.println("3. 查看所有薪资");
            }
            System.out.println("0. 返回");
            String c = input.nextLine().trim();
            switch (c) {
                case "1":
                    viewMySalary();
                    break;
                case "2":
                    if (hasPermission("salary")) issueSalary();
                    break;
                case "3":
                    if (hasPermission("salary")) viewAllSalaries();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效输入。");
            }
        }
    }

    // 权限检查
    private boolean hasPermission(String module) {
        Optional<Role> roleOpt = roleService.getPermissions(currentUserRole);
        if (!roleOpt.isPresent()) {
            System.out.println("权限加载失败。");
            return false;
        }
        Role r = roleOpt.get();
        switch (module) {
            case "employee": return r.isCanManageEmployee() || "employee".equals(currentUserRole);
            case "attendance": return r.isCanManageAttendance() || "employee".equals(currentUserRole);
            case "salary": return r.isCanManageSalary() || "employee".equals(currentUserRole);
            default: return false;
        }
    }

    // === 员工操作 ===
    private void viewAllEmployees() {
        List<Employee> emps = empService.viewAllEmployees();
        System.out.println("\n员工列表:");
        System.out.println("ID\t姓名\t部门\t职位\t角色");
        for (Employee e : emps) {
            System.out.printf("%d\t%s\t%s\t%s\t%s%n",
                    e.getEmpId(), e.getEmpName(), e.getDepartment(), e.getPosition(), e.getRole());
        }
    }

    private void addEmployee() {
        System.out.print("姓名: "); String name = input.nextLine().trim();
        System.out.print("部门: "); String dept = input.nextLine().trim();
        System.out.print("职位: "); String pos = input.nextLine().trim();
        System.out.print("角色 (admin/hr/employee): "); String role = input.nextLine().trim();
        System.out.print("密码: "); String pwd = input.nextLine().trim();
        if (empService.addEmployee(name, dept, pos, role, pwd)) {
            System.out.println("添加成功！");
        } else {
            System.out.println("添加失败（可能用户名重复）");
        }
    }

    private void updateEmployee() {
        System.out.print("员工ID: "); int id = Integer.parseInt(input.nextLine().trim());
        System.out.print("新姓名: "); String name = input.nextLine().trim();
        System.out.print("新部门: "); String dept = input.nextLine().trim();
        System.out.print("新职位: "); String pos = input.nextLine().trim();
        if (empService.updateEmployee(id, name, dept, pos)) {
            System.out.println("修改成功！");
        } else {
            System.out.println("修改失败。");
        }
    }

    private void deleteEmployee() {
        System.out.print("员工ID: "); int id = Integer.parseInt(input.nextLine().trim());
        if (empService.deleteEmployee(id)) {
            System.out.println("删除成功！");
        } else {
            System.out.println("删除失败。");
        }
    }

    // === 考勤操作 ===
    private void viewMyAttendance() {
        int empId = getMyEmpId();
        if (empId == -1) return;
        List<Attendance> list = attService.viewMyAttendance(empId);
        System.out.println("\n我的考勤:");
        for (Attendance a : list) {
            System.out.printf("日期: %s, 状态: %s%n", a.getDate(), a.getStatus());
        }
    }

    private void recordAttendance() {
        System.out.print("员工ID: "); int empId = Integer.parseInt(input.nextLine().trim());
        System.out.print("日期 (yyyy-MM-dd): ");
        LocalDate date = LocalDate.parse(input.nextLine().trim());
        System.out.print("状态 (present/absent/late): "); String status = input.nextLine().trim();
        if (attService.markAttendance(empId, date, status)) {
            System.out.println("考勤录入成功！");
        } else {
            System.out.println("录入失败。");
        }
    }

    private void viewAllAttendance() {
        List<Attendance> list = attService.viewAllAttendance();
        System.out.println("\n所有考勤记录:");
        for (Attendance a : list) {
            System.out.printf("ID: %d, 日期: %s, 状态: %s%n", a.getEmpId(), a.getDate(), a.getStatus());
        }
    }

    private void viewAttendanceByDate() {
        System.out.print("日期 (yyyy-MM-dd): ");
        LocalDate date = LocalDate.parse(input.nextLine().trim());
        List<Attendance> list = attService.viewAttendanceByDate(date);
        System.out.println("\n" + date + " 的考勤:");
        for (Attendance a : list) {
            System.out.printf("员工ID: %d, 状态: %s%n", a.getEmpId(), a.getStatus());
        }
    }

    // === 薪资操作 ===
    private void viewMySalary() {
        int empId = getMyEmpId();
        if (empId == -1) return;
        List<Salary> list = salService.viewMySalary(empId);
        System.out.println("\n我的薪资:");
        for (Salary s : list) {
            System.out.printf("月份: %s, 基本工资: %.2f, 奖金: %.2f, 总计: %.2f%n",
                    s.getMonth(), s.getBaseSalary(), s.getBonus(), s.getTotal());
        }
    }

    private void issueSalary() {
        System.out.print("员工ID: "); int empId = Integer.parseInt(input.nextLine().trim());
        System.out.print("基本工资: "); double base = Double.parseDouble(input.nextLine().trim());
        System.out.print("奖金: "); double bonus = Double.parseDouble(input.nextLine().trim());
        System.out.print("月份 (yyyy-MM): "); String month = input.nextLine().trim();
        if (salService.issueSalary(empId, base, bonus, month)) {
            System.out.println("薪资发放成功！");
        } else {
            System.out.println("发放失败。");
        }
    }

    private void viewAllSalaries() {
        List<Salary> list = salService.viewAllSalaries();
        System.out.println("\n所有薪资记录:");
        for (Salary s : list) {
            System.out.printf("员工ID: %d, 月份: %s, 总计: %.2f%n", s.getEmpId(), s.getMonth(), s.getTotal());
        }
    }

    // 工具方法：根据当前用户名获取 empId
    private int getMyEmpId() {
        List<Employee> emps = empService.viewAllEmployees();
        for (Employee e : emps) {
            if (e.getEmpName().equals(currentUserName)) {
                return e.getEmpId();
            }
        }
        System.out.println("未找到您的员工信息。");
        return -1;
    }

    private void logout() {
        currentUserName = null;
        currentUserRole = null;
        System.out.println("已退出系统。");
    }
}